const config = require("../configs.js");
const axios = require("axios");
const { exec } = require("child_process");
const { loadEnvConfig } = require("../env-config.js");
const { port } = loadEnvConfig();
const baseUrl = `http://localhost:${port}`;
const {
  getCurrentDate,
  convertMenuStringToArray,
  flatArrayToTree,
  findMenuByPath,
} = require("../utils/index.js");

// 启动 api.js
const startApiProcess = async () => {
  return new Promise((resolve, reject) => {
    // 获取当前环境变量
    const envVars = { ...process.env };

    const apiProcess = exec(
      "node api.js",
      {
        env: envVars, // 传递环境变量
        stdio: "pipe",
      },
      (error) => {
        if (error) {
          reject(error);
          return;
        }
      }
    );

    // 接收指定信息  判定服务是否运行
    const onData = (data) => {
      if (data.includes(baseUrl)) {
        apiProcess.stdout.off("data", onData);
        resolve(apiProcess);
      }
    };

    apiProcess.stdout.on("data", onData);

    // 主应用结束，自动关闭服务
    process.on("exit", () => {
      apiProcess.kill();
    });

    // 设置超时时间
    setTimeout(() => {
      apiProcess.stdout.off("data", onData);
      reject(new Error("服务启动超时，请重试"));
    }, 10000);
  });
};

/**
 * @description  快码设置 --- 新增快码
 * @returns {Promise<void>}
 */
const saveSysParam = async () => {
  const params = {
    paramValue: config.moduleName,
    paramDesc: `/${config.moduleName}`,
    paramGroupId: "25951782061",
    remark: config.menu,
    gradeValue: "",
  };

  const response = await axios.post(`${baseUrl}/sysParam/saveSysParam`, params);
  if (response.data.code === "200") {
    console.log("✅快码设置已添加");
  } else {
    throw new Error("快码添加失败，请重新添加");
  }
};

/**
 * @description  功能设置 --- 新增功能
 * @returns {Promise<void>}
 */
const sysCreate = async () => {
  const params = {
    functionTitle: `${config.moduleNameValue}JAVA`,
    functionKey: `/sys/Menu/JumpNewQMS?embedUrlCode=${config.moduleName}`,
    promission: config.btnPromission || [],
    waringDay: 30,
    waringTable: "/",
  };
  const response = await axios.post(
    `${baseUrl}/auth/addFunctionAction`,
    params
  );
  if (response.data.code === "200") {
    console.log("✅功能设置已添加");
  } else {
    throw new Error("功能添加失败，请重新添加");
  }
};

/**
 * @description  角色管理 --- 获取列表数据源
 * @returns {Promise<void>}
 */
let functionList = [];
const findSysFunctionPage = async (type = true) => {
  functionList = [];
  const params = {
    roleId: 5096725,
    functionPath: config.moduleName,
    functionState: "A",
    // functionPath: "test",
    // functionState: "D",
    // datetimeModifiedEnd: "2025-10-01",
    datetimeModifiedStart: type ? getCurrentDate() : "",
    current: 1,
    size: 10,
  };

  const response = await axios.post(
    `${baseUrl}/sysRole/findSysFunctionPage`,
    params
  );

  if (response.data.code === "200") {
    console.log("已获取（角色管理数据源）");
    // 获取records数组
    const records = response.data.data.records || [];
    functionList = records;
    console.log(`共获取到 ${records.length} 条记录`);

    // 如果是从配置菜单处请求   则无需进行后续操作
    if (!type) {
      return;
    }

    if (records.length === 0) {
      console.log("没有需要处理的数据");
      return;
    }

    // 为每个记录创建异步任务
    const promises = records.map((record, index) => {
      console.log(`开始处理第 ${index + 1} 条记录`);
      return roleFuntionCreateOrDelete(record);
    });

    // 等待所有异步任务完成
    await Promise.all(promises);
    console.log("✅所有角色功能勾选操作已完成");
  } else {
    throw new Error("角色管理数据源获取失败");
  }
};

/**
 * @description  角色管理 --- 新增JAVA功能勾选
 * @returns {Promise<void>}
 */
const roleFuntionCreateOrDelete = async (row) => {
  const params = {
    roleId: "5096725",
    ids: row.functionId,
    select: true,
  };

  await axios.post(`${baseUrl}/sysRole/roleFuntionCreateOrDelete`, params);
};

/**
 * @description  功能同步 --- 获取列表数据源
 * @param {string} functionPath - 要查询的功能路径
 * @param {string} functionTitle - 要查询的功能标题
 * @returns {Promise<void>}
 */
const sysFunctionListPage = async (functionPath, functionTitle) => {
  const params = {
    current: 1,
    size: 10,
    state: "A",
    dateEnd: getCurrentDate(),
    functionPath,
    functionTitle,
  };

  const response = await axios.post(`${baseUrl}/sys/function/listPage`, params);

  if (response.data.code === "200") {
    console.log("已获取功能同步数据源");
    // 获取records数组
    const records = response.data.data.records || [];
    console.log(`共获取到 ${records.length} 条记录`);

    if (records.length === 0) {
      console.log("没有需要处理的数据");
      return;
    }

    await syncSyncData(records, "FUNCTION");
    console.log("✅所有功能同步已完成");
  } else {
    throw new Error("功能同步数据源获取失败");
  }
};

/**
 * @description  执行所有（功能同步）任务
 * @returns {Promise<void>}
 */
const executeAllSyncTasks = async (type) => {
  // 如果配置多个功能   则进行多个功能同步
  if (config.synchronization && config.synchronization.length > 0) {
    for (const syncItem of config.synchronization) {
      try {
        console.log(`开始处理（功能同步）: ${syncItem.functionTitle}`);
        await sysFunctionListPage(
          syncItem.functionPath,
          syncItem.functionTitle
        );
      } catch (error) {
        console.error(
          `处理（功能同步） ${syncItem.functionTitle} 时出错:`,
          error.message
        );
      }
    }
  } else {
    // 未配置synchronization 则取当前生成的模块默认值
    const functionTitle =
      convertMenuStringToArray()?.[convertMenuStringToArray().length - 1];
    await sysFunctionListPage(
      config.moduleName,
      functionTitle || config.moduleNameValue
    );
  }
};

/**
 * @description  快码同步 --- 获取列表数据源
 * @param {string} paramValue - 要查询的快码路径
 * @param {string} remark - 要查询的快码备注
 * @returns {Promise<void>}
 */
const sysParamFindListPage = async (paramValue, remark) => {
  const params = {
    current: 1,
    size: 10,
    state: "A",
    endTime: getCurrentDate(),
    paramValue,
    remark,
  };

  const response = await axios.post(`${baseUrl}/sysParam/findListPage`, params);

  if (response.data.code === "200") {
    console.log("已获取（快码同步）数据源");
    // 获取records数组
    const records = response.data.data.records || [];
    console.log(`共获取到 ${records.length} 条记录`);

    if (records.length === 0) {
      console.log("没有需要处理的数据");
      return;
    }

    await syncSyncData(records, "PARAM");
    console.log("✅所有（快码同步）已完成");
  } else {
    throw new Error("（快码同步）数据源获取失败");
  }
};

/**
 * @description  执行所有（快码同步）任务
 * @returns {Promise<void>}
 */
const executeAllSysParam = async (type) => {
  // 如果配置多个功能   则进行多个功能同步
  if (config.synchronization && config.synchronization.length > 0) {
    for (const syncItem of config.synchronization) {
      try {
        console.log(`开始处理（快码同步）: ${syncItem.functionTitle}`);
        await sysParamFindListPage(
          syncItem.functionPath,
          syncItem.functionTitle
        );
      } catch (error) {
        console.error(
          `处理（快码同步） ${syncItem.functionTitle} 时出错:`,
          error.message
        );
      }
    }
  } else {
    // 未配置synchronization 则取当前生成的模块默认值
    const functionTitle =
      convertMenuStringToArray()?.[convertMenuStringToArray().length - 1];
    await sysParamFindListPage(
      config.moduleName,
      functionTitle || config.moduleNameValue
    );
  }
};

/**
 * @description  获取菜单数据
 * @returns {Promise<void>}
 */
const sysMenuList = async () => {
  // 是否进行过角色勾选   如果未进行过需要获取当前功能数据
  if (functionList.length === 0) {
    await findSysFunctionPage(false);
  }

  if (functionList.length === 0) {
    throw new Error("该菜单未配置功能模块，请先配置对应功能");
  }

  // 获取所有菜单数据
  const response = await axios.get(`${baseUrl}/sysMenu/menuList`);

  if (response.data.code === "200") {
    console.log("已获取（菜单数据）");
    const matchedMenu = menuTreeManage(response.data.data);
    if (matchedMenu) {
      console.log("已找到（匹配菜单）");
      // 先获取带有层级的菜单数据
      const parentMenuData = await sysMenuParentMenu();
      // 获取菜单序号
      const level = parentMenuData.find(
        (it) => it.id === String(matchedMenu.id)
      )?.menuLevel;
      const menuOrder = await sysMenuListPage(matchedMenu.id);

      // 保存新增菜单
      const params = {
        parentMenuId: matchedMenu.id,
        menuTitle: config.moduleNameValue,
        menuLevel: Number(level) + 1,
        menuOrder,
        functionId: functionList?.[0]?.functionId,
        functionText: functionList?.[0]?.functionTitle,
      };
      const saveRes = await axios.post(`${baseUrl}/sysMenu/save`, params);

      if (saveRes.data.code === "200") {
        console.log("✅菜单新增成功");
      } else {
        throw new Error(saveRes.data.msg);
      }
    } else {
      throw new Error(`未找到匹配路径:${menuPathArray}`);
    }
  } else {
    throw new Error(response.data.msg);
  }
};

/**
 * @description  菜单字符处理
 * @returns {string}
 */
const menuTreeManage = (data) => {
  // 1. 获取菜单树
  const menuTree = flatArrayToTree(data);

  // 2. 转换菜单路径为数组（如 "成品品质管理 / 成品不合格管理 / 样机不合格流程台账" -> ["成品品质管理", "成品不合格管理"]）
  // 此处需要去掉最后一项，因为它是当前模块的名称
  const menuPathArray = convertMenuStringToArray().slice(0, -1);

  // 3. 递归查找匹配的菜单项
  const matchedMenu = findMenuByPath(menuTree, menuPathArray);

  return matchedMenu;
};
/**
 * @description  获取菜单层级数据
 * @returns {Promise<void>}
 */
const sysMenuParentMenu = async () => {
  const response = await axios.get(`${baseUrl}/sysMenu/parentMenu`);

  if (response.data.code === "200") {
    console.log("已获取（菜单层级数据）");
    return response.data.data;
  } else {
    console.log("菜单层级数据获取失败");
    return [];
  }
};

/**
 * @description  获取菜单序号数据
 * @returns {Promise<number>}
 */
const sysMenuListPage = async (id) => {
  const params = {
    current: 1,
    size: 500,
    state: "A",
    menuTreeSelected: id,
  };

  const response = await axios.post(`${baseUrl}/sysMenu/listPage`, params);

  if (response.data.code === "200") {
    console.log("已获取（菜单序号数据）");
    // 获取records数组
    const records = response.data.data.records || [];
    console.log(`共获取到 ${records.length} 条记录`);

    if (records.length === 0) {
      console.log("没有需要处理的数据");
      return;
    }

    // 先查询是否有老系统菜单
    const oldMenu = records.find(
      (item) => item.menuTitle === config.moduleNameValue
    );

    if (oldMenu) {
      // 如果查到  则返回当前数据索引+0.1
      return Number(oldMenu.menuOrder) + 0.1;
    } else {
      // 没查到则索引为当前最大索引+1
      return Math.max(...records.map((item) => item.menuOrder)) + 1;
    }
  } else {
    console.log("（菜单序号数据）获取失败");
  }
};

/**
 * @description  同步  ---  对应功能进行同步
 * @returns {Promise<void>}
 */
const syncSyncData = async (records, dataType) => {
  const params = {
    to: config.synchronizationEnv.to,
    dataType,
    idList: records.map((item) => item.id),
  };

  await axios.post(`${baseUrl}/sync/syncData`, params);
};

// 主执行函数
const main = async () => {
  // // 先启动 API 服务并等待它准备好
  // await startApiProcess();

  // // 快码设置 --- 新增快码
  // await saveSysParam();
  // // 功能设置 --- 新增功能
  // await sysCreate();
  // // 角色管理 --- 获取当前模块数据源   勾选对应功能权限
  // await findSysFunctionPage();
  // // 菜单设置 --- 新增菜单
  // await sysMenuList();

  // 根据配置决定是否需要同步功能
  if (config.synchronizationEnv.execute) {
    // 功能同步
    await executeAllSyncTasks();
    // 快码同步
    await executeAllSysParam();
  }
};

module.exports = {
  main,
};
